
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Kafka是怎么保证消息可靠性的？ - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>Kafka是怎么保证消息可靠性的？ - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Kafka生产者提供了哪三种消息确认机制（acks）来保障不同级别的消息可靠性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Kafka生产者提供了三种消息确认机制：acks=0（生产者不等待任何确认）、acks=1（leader副本收到消息后即发送确认）、acks=all（leader和所有副本都确认消息后，生产者才收到确认）。</div>
          </div>
          <div class="card-source">来源: 生产者发送消息</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">什么是Kafka中的ISR（In-Sync Replica）机制？它如何保证消息的一致性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">ISR是Kafka维护的一个包含了所有已复制最新消息的副本集合。只有ISR中的副本才能参与消息的读写操作，这保证了消息的一致性。当follower副本落后于leader副本时，Kafka会将其从ISR集合中移除，直到它追赶上进度。</div>
          </div>
          <div class="card-source">来源: 消息复制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当Kafka分区的Leader副本发生故障时，系统是如何通过故障转移来保证消息可靠性的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">故障转移过程包括四个步骤：1. Kafka集群检测到Leader副本故障。2. 从ISR（In-Sync Replicas）中选择一个健康的Follower副本晋升为新的Leader。3. 新Leader将其上的未提交消息复制到其他Follower。4. 消费者被重定向到新的Leader副本，确保消息的持续可用性。</div>
          </div>
          <div class="card-source">来源: 故障转移</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">Kafka消费者是如何利用偏移量（offset）管理来确保消息被可靠消费的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Kafka通过偏移量（offset）来跟踪消费者消费的位置。消费者从特定分区的特定偏移量开始消费，并定期提交当前偏移量。如果消费者发生故障，它可以根据之前提交的偏移量重新定位到故障前的位置，从而继续消费。</div>
          </div>
          <div class="card-source">来源: 消费者</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">流程</div>
          <div class="card-question">描述一下消息从被发送到Leader副本后，其写入和同步到Follower副本的基本流程是怎样的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">流程</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">流程如下：1. 消息首先被写入Leader副本所在的Broker。2. Leader副本将消息同步写入其本地日志文件。3. Leader副本异步地将消息复制到所有的Follower副本。4. Follower副本成功复制消息后，会向Leader发送确认。</div>
          </div>
          <div class="card-source">来源: Leader 副本写入</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Kafka中的消费者组（Consumer Group）发生重平衡（Rebalance）的触发条件是什么？其目的是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当有消费者加入或离开消费者组时，会触发重平衡机制。其目的是重新分配分区给组内的消费者，以确保每个分区在同一时间只被消费者组中的一个消费者消费，从而保证消息被正确地消费。</div>
          </div>
          <div class="card-source">来源: 消费者</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在Kafka中，消息持久化是如何实现的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Kafka使用磁盘持久化来确保消息的持久性。生产者发送的消息首先被写入到Kafka Broker的内存（操作系统的页缓存）中，然后异步地刷写到磁盘。这种机制确保即使发生系统故障或重启，消息也不会丢失。</div>
          </div>
          <div class="card-source">来源: 消息复制和持久化</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">在Kafka的副本机制中，Leader副本和Follower副本各自扮演什么角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在一个分区中，有且仅有一个Leader副本和若干个Follower副本。生产者将消息发送到Leader副本，然后Leader副本负责将消息复制到所有的Follower副本，实现数据的冗余和高可用。</div>
          </div>
          <div class="card-source">来源: 消息复制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在ISR确认机制中，Leader副本在什么条件下才会将消息提交到自己的日志文件，并认为消息已被成功写入？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在Leader副本收到ISR（In-Sync Replicas）中足够数量的Follower副本的确认后，它会将消息提交到自己的日志文件中。这个动作表示消息已经被成功复制到了ISR中的所有副本，从而保证了消息的可靠性。</div>
          </div>
          <div class="card-source">来源: ISR确认机制</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
